package com.coder4j.system.service;

import com.alibaba.fastjson.JSON;
import com.coder4j.cache.GroupCache;
import com.coder4j.config.GlobalConfig;
import com.coder4j.starter.tools.util.ListUtils;
import com.coder4j.starter.tools.util.StringUtils;
import com.coder4j.starter.tools.vo.BaseException;
import com.coder4j.starter.web.OptionVO;
import com.coder4j.starter.web.TreeNodeVO;
import com.coder4j.system.entity.SysGroupEntity;
import com.coder4j.enums.SysGroupTypeEnum;
import com.coder4j.system.mapper.SysGroupMapper;
import com.coder4j.system.vo.SysGroupQuery;
import com.coder4j.system.vo.SysGroupVO;
import com.coder4j.starter.web.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分组
 *
 * @author keller
 * @date 2024-05-07 18:19:35
 */
@Service
@Slf4j
public class SysGroupService extends BaseServiceImpl<SysGroupMapper, SysGroupEntity, SysGroupVO>   {

    @Resource
    private SysGroupMapper mapper;

    @Override
    public SysGroupVO entity2Vo(SysGroupEntity entity) {
        SysGroupVO vo = new SysGroupVO();
        BeanUtils.copyProperties(entity, vo);
        vo.setTypeName(SysGroupTypeEnum.getTitle(vo.getType()));
        vo.setParentName(GroupCache.getGroupName(vo.getParentId()));
        if(StringUtils.notEmpty(entity.getExtend())){
            vo.setExtendJson(JSON.parseArray(entity.getExtend()));
        }
        return vo;
    }

    @Override
    public SysGroupEntity vo2Entity(SysGroupVO vo) {
        SysGroupEntity entity = new SysGroupEntity();
        BeanUtils.copyProperties(vo, entity);
        if(vo.getExtendJson() != null){
            entity.setExtend(vo.getExtendJson().toJSONString());
        }
        return entity;
    }

    public List<OptionVO<Long>> getOptionList(SysGroupQuery query) {

        List<SysGroupEntity> list = this.baseQueryList(query);

        List<OptionVO<Long>> voList = new ArrayList<>();
        if (ListUtils.isEmpty(list)) {
            return voList;
        }
        for (SysGroupEntity group : list) {
            OptionVO<Long> option = new OptionVO<>(group.getName(), group.getId());
            voList.add(option);
        }

        return voList;
    }

    public void save(SysGroupVO vo) {
        SysGroupEntity entity = this.vo2Entity(vo);
        String parentLevel = GlobalConfig.RootLevelPath;

        //默认为一级分组
        if (entity.getParentId() == null) {
            entity.setParentId(GlobalConfig.RootId);
        }

        Long parentId = entity.getParentId();
        if (!SysGroupTypeEnum.contains(entity.getType())) {
            throw BaseException.error("未识别的分组类型");
        }
        //校验父节点
        if (!GlobalConfig.RootId.equals(parentId)) {
            SysGroupEntity parent = this.baseGetById(parentId);
            if (parent == null) {
                throw BaseException.error("父分组不存在");
            }
            parentLevel = parent.getLevelPath();
        }
        //更新
        if (entity.getId() != null) {
            //ID和parentId一致，有问题
            if (entity.getId().equals(entity.getParentId())) {
                throw BaseException.errorData();
            }
        } else {
            //添加，先保存数据，生成自增ID
            entity = this.baseSave(entity);
        }
        //将ID更新到层级路径上
        entity.setLevelPath(parentLevel + "_" + entity.getId());
        //如果没有业务编码，生成一个
        if(StringUtils.isEmpty(entity.getBizCode())){
            entity.setBizCode(entity.getType()+"_"+entity.getId());
        }
        this.baseUpdateById(entity);
    }

    public TreeNodeVO getTreeSelector(String type, Long id) {
        SysGroupQuery query = new SysGroupQuery();
        query.setType(type);

        List<SysGroupEntity> list = this.baseQueryList(query);

        TreeNodeVO root = new TreeNodeVO();
        root.setId(GlobalConfig.RootId);
        root.setLabel(SysGroupTypeEnum.valueOf(type).title);
        root.setValue(GlobalConfig.RootId + "");
        if (ListUtils.isEmpty(list)) {
            return root;
        }

        if(id != null){
            list = list.stream().filter(item -> !item.getId().equals(id)).collect(Collectors.toList());
            if (ListUtils.isEmpty(list)) {
                return root;
            }
        }

        List<TreeNodeVO> voList = new ArrayList<>();
        for (SysGroupEntity entity : list) {
            TreeNodeVO treeNodeVO = new TreeNodeVO();
            treeNodeVO.setId(entity.getId());
            treeNodeVO.setParentId(entity.getParentId());

            treeNodeVO.setLabel(entity.getName());
            treeNodeVO.setValue(entity.getId() + "");

            treeNodeVO.setKey(entity.getId() + "");
            treeNodeVO.setTitle(entity.getName());

            treeNodeVO.setOriginal(entity);

            voList.add(treeNodeVO);
        }

        this.baseInitChildren(root, voList);
        return root;
    }

    public TreeNodeVO getTagTree() {
        SysGroupTypeEnum tag = SysGroupTypeEnum.Tag;
        SysGroupQuery query = new SysGroupQuery();
        query.setType(tag.name());

        List<SysGroupEntity> list = this.baseQueryList(query);
        TreeNodeVO root = new TreeNodeVO();
        root.setId(GlobalConfig.RootId);
        root.setLabel(tag.title);
        root.setValue(GlobalConfig.RootId + "");
        if (ListUtils.isEmpty(list)) {
            return root;
        }

        List<TreeNodeVO> voList = new ArrayList<>();
        for (SysGroupEntity entity : list) {
            TreeNodeVO treeNodeVO = new TreeNodeVO();
            treeNodeVO.setId(entity.getId());
            treeNodeVO.setParentId(entity.getParentId());
            treeNodeVO.setValue(entity.getId()+"^_^"+entity.getBizCode()+"^_^"+entity.getName());
            treeNodeVO.setTitle(entity.getName());
            treeNodeVO.setOriginal(entity);
            voList.add(treeNodeVO);
        }

        this.baseInitChildren(root, voList);
        return root;
    }
}
